import ast
import os
from typing import Dict, List
from .code_analyzer import CodeAnalyzer

class ErrorFixer:
    """代码错误自动修复工具"""
    
    def __init__(self):
        self.analyzer = CodeAnalyzer()
    
    def fix_file(self, file_path: str, backup: bool = True) -> Dict:
        """修复单个文件中的错误"""
        if backup:
            self._create_backup(file_path)
        
        try:
            with open(file_path, "r", encoding="utf-8") as f:
                code = f.read()
            
            # 分析代码问题
            analysis = self.analyzer.analyze_file(file_path)
            if analysis["status"] == "error":
                return {
                    "status": "error",
                    "message": f"分析失败: {analysis['error']}"
                }
            
            # 修复检测到的问题
            fixed_code, fixes = self._apply_fixes(code, analysis["issues"])
            
            # 保存修复后的代码
            with open(file_path, "w", encoding="utf-8") as f:
                f.write(fixed_code)
            
            return {
                "status": "success",
                "fixed_issues": len(fixes),
                "fixes": fixes
            }
        except Exception as e:
            return {
                "status": "error",
                "message": f"修复失败: {str(e)}"
            }
    
    def _create_backup(self, file_path: str):
        """创建文件备份"""
        backup_path = f"{file_path}.bak"
        if not os.path.exists(backup_path):
            with open(file_path, "r", encoding="utf-8") as f_in, \
                 open(backup_path, "w", encoding="utf-8") as f_out:
                f_out.write(f_in.read())
    
    def _apply_fixes(self, code: str, issues: List[Dict]) -> Tuple[str, List[Dict]]:
        """应用修复逻辑"""
        lines = code.splitlines()
        fixes = []
        
        # 按行号降序处理，避免修改后行号变化影响后续修复
        for issue in sorted(issues, key=lambda x: x["line"], reverse=True):
            if issue["type"] == "unused_variable":
                # 移除未使用的变量赋值
                line_num = issue["line"] - 1  # 转换为0索引
                if 0 <= line_num < len(lines):
                    original_line = lines[line_num]
                    # 简单处理：注释掉未使用的变量行
                    lines[line_num] = f"# 自动修复：移除未使用的变量 {issue['message'].split(': ')[1]}\n# {original_line}"
                    fixes.append({
                        "type": issue["type"],
                        "line": issue["line"],
                        "original": original_line,
                        "fixed": lines[line_num]
                    })
            
            elif issue["type"] == "high_complexity":
                # 高复杂度函数提示（无法自动修复，添加TODO注释）
                line_num = issue["line"] - 1
                if 0 <= line_num < len(lines):
                    # 在函数定义前添加注释
                    lines.insert(line_num, f"# TODO: 自动检测：函数复杂度较高，建议拆分 {issue['message'].split(': ')[1]}")
                    fixes.append({
                        "type": issue["type"],
                        "line": issue["line"],
                        "message": "添加了拆分建议注释"
                    })
        
        return "\n".join(lines), fixes
    
    def fix_directory(self, dir_path: str, backup: bool = True) -> Dict:
        """修复目录中所有文件的错误"""
        results = {
            "total_files": 0,
            "fixed_files": 0,
            "total_fixes": 0,
            "errors": []
        }
        
        for root, _, files in os.walk(dir_path):
            for file in files:
                if file.endswith(".py") and not file.endswith(".bak"):
                    results["total_files"] += 1
                    file_path = os.path.join(root, file)
                    try:
                        fix_result = self.fix_file(file_path, backup)
                        if fix_result["status"] == "success":
                            results["fixed_files"] += 1
                            results["total_fixes"] += fix_result["fixed_issues"]
                        else:
                            results["errors"].append({
                                "file": file_path,
                                "message": fix_result["message"]
                            })
                    except Exception as e:
                        results["errors"].append({
                            "file": file_path,
                            "message": str(e)
                        })
        
        return results